﻿using AiQiuQuan.Sport.Model.Enums;
using AiQiuQuan.Sport.Model.Models;
using AiQiuQuan.Sport.WebApi.Entities;
using AiQiuQuan.Sport.WebApi.Repositories;
using MapsterMapper;
using Microsoft.EntityFrameworkCore;

namespace AiQiuQuan.Sport.WebApi.Services.Impl
{
    /// <summary>
    /// 课程学生及记录
    /// </summary>
    public class CourseStudentService : ICourseStudentService
    {
        private readonly IMapper _mapper;
        private readonly ICourseStudentRepository _courseStudentRepository;
        private readonly ICourseStuentRecordRepository _courseStuentRecordRepository;

        /// <summary>
        /// ctor
        /// </summary>
        public CourseStudentService(
            IMapper mapper,
            ICourseStudentRepository courseStudentRepository,
            ICourseStuentRecordRepository courseStuentRecordRepository)
        {
            _mapper = mapper;
            _courseStudentRepository = courseStudentRepository;
            _courseStuentRecordRepository = courseStuentRecordRepository;
        }

        /// <summary>
        /// 课程记录新增及学生新增或更新
        /// </summary>
        public async Task AddRecordAsync(CourseStuentRecordAddDto model)
        {
            var student = await _courseStudentRepository.FirstOrDefaultAsync(m => m.CourseId == model.CourseId && m.UserId == model.UserId);
            if (student == null)
            {
                student = new CourseStudent
                {
                    UserId = model.UserId,
                    CourseId = model.CourseId,
                    CourseType = model.CourseType,
                    TimesCount = model.ChangeCount,
                    UseCount = 0,
                    StartTime = model.StartTime.Value,
                    EndTime = model.EndTime,
                    IsEnable = true
                };
                switch (model.CourseType)
                {
                    case CourseTypeEnum.Times:
                        student.EndTime = student.StartTime.Value.AddMonths(model.ValidMonth);
                        break;
                    case CourseTypeEnum.Duration:
                        student.StartTime = model.StartTime;
                        student.EndTime = student.StartTime.Value.AddMonths(model.ValidMonth);
                        break;
                    case CourseTypeEnum.Activity:
                        student.StartTime = model.StartTime;
                        student.EndTime = model.EndTime;
                        break;
                }

                await _courseStudentRepository.AddAsync(student);
            }
            else
            {
                student.TimesCount += model.ChangeCount;
                student.TimesCount = student.TimesCount < 0 ? 0 : student.TimesCount;
                if (model.OpereateType == CourseRecordOperateTypeEnum.Paid)
                {
                    student.IsEnable = true;
                    switch (model.CourseType)
                    {
                        case CourseTypeEnum.Times:
                            student.EndTime = student.StartTime.Value.AddMonths(model.ValidMonth);
                            break;
                        case CourseTypeEnum.Duration:
                            student.StartTime = model.StartTime;
                            student.EndTime = student.StartTime.Value.AddMonths(model.ValidMonth);
                            break;
                        case CourseTypeEnum.Activity:
                            student.StartTime = model.StartTime;
                            student.EndTime = model.EndTime;
                            break;
                    }

                    await _courseStudentRepository.UpdateAsync(student);
                }
                else if (model.OpereateType == CourseRecordOperateTypeEnum.Refund)
                {
                    switch (model.CourseType)
                    {
                        case CourseTypeEnum.Times:
                            student.IsEnable = student.TimesCount > 0;
                            await _courseStudentRepository.UpdateAsync(student);
                            break;
                        case CourseTypeEnum.Duration:
                        case CourseTypeEnum.Activity:
                            var studentBuilder = await _courseStudentRepository.UpdatePartialAsync();
                            await studentBuilder.Set(m => m.IsEnable, false)
                                .Where(m => m.CourseId == model.CourseId && m.UserId == model.UserId)
                                .ExecuteAsync();
                            break;
                    }
                }
                else if (model.OpereateType == CourseRecordOperateTypeEnum.Call)
                {
                    if (model.CourseType == CourseTypeEnum.Times)
                    {
                        student.IsEnable = student.TimesCount > 0;
                        student.UseCount += Math.Abs(model.ChangeCount);
                        await _courseStudentRepository.UpdateAsync(student);
                    }
                }
            }

            var record = _mapper.Map<CourseStuentRecord>(model);
            record.TimesCount = student.TimesCount;
            await _courseStuentRecordRepository.AddAsync(record);
        }
    }
}
